package cn.edu.seu.ssny.controller.admin.system;

import cn.edu.seu.ssny.common.JsonResult;
import cn.edu.seu.ssny.common.R;
import cn.edu.seu.ssny.enums.ResultCodeEnum;
import cn.edu.seu.ssny.common.utils.FileUtils;
import cn.edu.seu.ssny.controller.BaseController;
import cn.edu.seu.ssny.entity.*;
import cn.edu.seu.ssny.exception.SsnyException;
import cn.edu.seu.ssny.service.IEquipmentService;
import cn.edu.seu.ssny.service.IProjectService;
import cn.edu.seu.ssny.service.IRoleService;
import cn.edu.seu.ssny.service.ISysClassService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.persistence.criteria.*;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.*;

@Controller
@RequestMapping("/admin/project")
public class ProjectController extends BaseController {
    private final static Logger logger = LoggerFactory.getLogger(ProjectController.class);


    @Autowired
    private IProjectService projectService;

    @Autowired
    private ISysClassService sysClassService;

    @Autowired
    private IEquipmentService equipmentService;

    @Value("${file.uploadFolder}")
    private String fileFolder;

    @Value("${file.url}")
    private String fileUrl;

    @RequestMapping(value = {"/", "/index"})
    public String index() {
        return "admin/project/index";
    }

    @RequestMapping(value = {"/list"})
    @ResponseBody
    public Page<Project> list(HttpSession session) {
        User currUser = (User) session.getAttribute("currUser");
        Enterprise enterprise = (Enterprise) session.getAttribute("enterprise");
        List<Project> projects;
        if (currUser.getRole().getLevel() != IRoleService.SUPER_LEVEL) {
            projects = currUser.getProjects();
        } else {
            projects = projectService.findAllByEnterprise(enterprise);
        }
        List<Integer> pids = new ArrayList<>();
        for (Project project : projects)
            pids.add(project.getId());

        Specification<Project> specification = new Specification<Project>() {
            @Override
            public Predicate toPredicate(Root<Project> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> predicatesList = new ArrayList<>();
                predicatesList.add(root.get("id").in(pids));
                Predicate[] predicates = new Predicate[predicatesList.size()];
                return cb.and(predicatesList.toArray(predicates));
            }
        };
        Page<Project> page = projectService.findAll(specification, getPageRequest());
        return page;
    }

    @GetMapping("/add")
    public String add(ModelMap map) {
        return "admin/project/form";
    }

    @GetMapping("/edit/{id}")
    public String edit(@PathVariable Integer id, ModelMap map) {
        Project project = projectService.find(id);
        map.put("project", project);
        return "admin/project/form";

    }

    @PostMapping("/edit")
    @ResponseBody
    public R edit(Project project, HttpSession session) {
        projectService.saveOrUpdate(project, (Enterprise) session.getAttribute("enterprise"));
        return R.ok();
    }

    @DeleteMapping(value = "/delete/{id}")
    @ResponseBody
    public R delete(@PathVariable Integer id) {
        projectService.delete(id);
        return R.ok();
    }

    @DeleteMapping("/deletems/{ids}")
    @ResponseBody
    public R deletems(@PathVariable String ids) {
        String[] idArray = ids.split("&");
        for (String id : idArray) {
            projectService.delete(Integer.parseInt(id));
        }
        return R.ok();
    }

    @GetMapping("/display/{id}")
    public String display(@PathVariable Integer id, ModelMap map) {
        Project project = projectService.find(id);
        map.put("project", project);
        return "admin/project/display";
    }

    @PostMapping("/display/edit")
    @ResponseBody
    public JsonResult displayEdit(Project project, ModelMap map, HttpSession session) {
        try {
            projectService.saveDisplay(project);
        } catch (Exception e) {
            return JsonResult.failure(e.getMessage());
        }
        return JsonResult.success();
    }

    @GetMapping("/panel/{id}")
    public String panel(@PathVariable Integer id, ModelMap map) {
        Project project = projectService.find(id);
        map.put("project", project);
        return "admin/project/panel";
    }

    @PostMapping("/panel/edit")
    @ResponseBody
    public JsonResult panelEdit(Project project) {
        try {
            projectService.savePanel(project);
        } catch (Exception e) {
            return JsonResult.failure(e.getMessage());
        }
        return JsonResult.success();
    }


    /**
     * 功能描述
     * <上传项目底图或者面板图,并且返回图片的url
     *
     * @param file
     * @param type      0:上传底图 1:上传面板图
     * @param projectId
     * @return
     */
    @ResponseBody
    @PostMapping("/image/upload")
    public R upload_image(HttpSession session, @RequestParam("file") MultipartFile file, @RequestParam("type") int type, @RequestParam("projectId") int projectId) throws IOException {
        String newFileName = FileUtils.upload(file, fileFolder);
        Project project = projectService.find(projectId);
        String url = fileUrl + newFileName;
        if (type == 0) {
            project.setImage(url);
        } else if (type == 1) {
            project.setPanel(url);
        } else {
            throw new SsnyException(ResultCodeEnum.ERROR_PARAMETER_VALIDATION);
        }
        projectService.saveOrUpdate(project, null);
        Map<String, Object> data = new HashMap<>();
        data.put("url", url);
        return R.ok().data(data);
    }

    /**
     * 功能描述：
     * <返回系统类别界面
     *
     * @return
     */
    @GetMapping("/sysclass/{projectId}")
    public String sysClass(@PathVariable("projectId") Long projectId, ModelMap map) {
        map.put("projectId", projectId);
        return "admin/project/sysclass";
    }

    /**
     * 功能描述：
     * <根据项目ID返回该项目的所有系统类名
     *
     * @return
     */
    @ResponseBody
    @GetMapping("/sysclass/list/{projectId}")
    public R findAllSysClassByProjectId(@PathVariable("projectId") Long projectId, @RequestParam(value = "order", required = false) String order) {
        List<SysClass> sysClasses = sysClassService.findAllByProjectId(projectId);
        Map<String, Object> data = new HashMap<>();
        data.put("sysclasses", sysClasses);
        return R.ok().data(data);
    }

    /**
     * 功能描述:
     * <返回添加或者修改系统分类界面
     *
     * @param sysClassId
     * @param map
     * @return
     */
    @GetMapping("/sysclass/add_edit/{projectId}")
    public String sysClassAddOrEditHtml(@PathVariable("projectId") Long projectId, @RequestParam(value = "sysClassId", required = false) Long sysClassId, ModelMap map) {
        if (sysClassId != null) {
            SysClass sysClass = sysClassService.findById(sysClassId);
            map.put("sysClass", sysClass);
        } else {
            SysClass sysClass = new SysClass();
            sysClass.setProjectId(projectId);
            map.put("sysClass", sysClass);
        }

        return "/admin/project/sysclass_add_edit";
    }

    @ResponseBody
    @PostMapping("/sysclass/add_edit")
    public R sysClassAddOrEdit(SysClass sysClass) {
        if (sysClassService.findByProjectIdAndClassName(sysClass.getProjectId(), sysClass.getClassName()) != null) {
            throw new SsnyException(ResultCodeEnum.ERROR_DUPLICATE_SYSCLASSNAME);
        }
        if (sysClass.getId() == null) {
            //添加
            sysClassService.save(sysClass);
        } else {
            //修改
            sysClassService.update(sysClass);
            List<Equipment> equipments = equipmentService.findBySysClassId(sysClass.getId());
            for (Equipment equipment : equipments) {
                equipment.setSysType(sysClass.getClassName());
                equipmentService.update(equipment);
            }
        }
        return R.ok();
    }

    /**
     * 功能描述：
     * <根据项目ID返回该项目的所有系统类名
     *
     * @return
     */
    @ResponseBody
    @PostMapping("/sysclass/add/{projectId}")
    public R sysClassAdd(@PathVariable("projectId") Long projectId, @RequestParam(value = "order", required = false) String order) {
        List<SysClass> sysClasses = sysClassService.findAllByProjectId(projectId);
        Map<String, Object> data = new HashMap<>();
        data.put("sysclasses", sysClasses);
        return R.ok().data(data);
    }

    /**
     * 功能描述：
     * <删除系统分类
     *
     * @return
     */
    @ResponseBody
    @DeleteMapping("/sysclass/{sysClassId}")
    public R sysClassDelete(@PathVariable("sysClassId") Long sysClassId) {
        List<Equipment> equipments = equipmentService.findBySysClassId(sysClassId);
        if (equipments != null && equipments.size() != 0) {
            throw new SsnyException(ResultCodeEnum.ERROR_SYSCLASS_USING);
        }
        sysClassService.delete(sysClassId);
        return R.ok();
    }


}
